package com.aizuda.easyManagerTool.service.setting.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.json.JSONUtil;
import cn.hutool.jwt.JWT;
import com.aizuda.easy.security.code.BasicCode;
import com.aizuda.easy.security.domain.Rep;
import com.aizuda.easy.security.domain.Req;
import com.aizuda.easy.security.exp.impl.BasicException;
import com.aizuda.easy.security.properties.SecurityProperties;
import com.aizuda.easy.security.server.EasySecurityServer;
import com.aizuda.easyManagerTool.domian.bo.PackagesBO;
import com.aizuda.easyManagerTool.domian.dto.PageDTO;
import com.aizuda.easyManagerTool.domian.dto.setting.SettingUserLoginDTO;
import com.aizuda.easyManagerTool.domian.dto.setting.SettingUserRegisterDTO;
import com.aizuda.easyManagerTool.domian.entity.setting.SettingUserEntity;
import com.aizuda.easyManagerTool.domian.vo.PageVO;
import com.aizuda.easyManagerTool.domian.vo.setting.SettingUserVO;
import com.aizuda.easyManagerTool.mapper.setting.SettingUserMapper;
import com.aizuda.easyManagerTool.service.setting.PackageCheckService;
import com.aizuda.easyManagerTool.service.setting.SettingRechargeService;
import com.aizuda.easyManagerTool.service.setting.SettingUserService;
import com.aizuda.easyManagerTool.util.AssertUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Service("user")
public class SettingUserServiceImpl extends ServiceImpl<SettingUserMapper, SettingUserEntity> implements SettingUserService, EasySecurityServer, PackageCheckService {

    @Resource
    SettingUserMapper settingUserMapper;
    @Resource
    SecurityProperties securityProperties;
    @Resource
    SettingRechargeService settingRechargeService;

    @Override
    public Rep<SettingUserVO> login(Req<SettingUserLoginDTO, SettingUserVO> req) {
        SettingUserLoginDTO data = req.getData();
        AssertUtil.objIsNull(data.getAccount(), "账号或密码不能为空");
        AssertUtil.objIsNull(data.getPassword(), "账号或密码不能为空");
        AssertUtil.objIsNull(data.getCode(), "请进行验证");
        if (StrUtil.isEmpty(codeMap.get(data.getCode()))) {
            AssertUtil.objIsNull(null, "验证失效，重新验证");
        }
        data.setPassword(encryptionPassword(data.getPassword(), data.getAccount()));
        SettingUserEntity settingUserEntity = settingUserMapper.findByAccountAndPassword(data);
        AssertUtil.objIsNull(settingUserEntity, "账号或密码错误");
        SettingUserVO settingUserVO = new SettingUserVO();
        BeanUtil.copyProperties(settingUserEntity,settingUserVO,"userPassword","createTime","updateTime","deleteFlag");
//        PackagesBO packageBO = settingRechargeService.findPackage(settingUserEntity.getTenantId());
//        settingUserVO.setPackageBO(packageBO);
        String token = JWT.create()
                .setPayload("user", JSONUtil.toJsonStr(settingUserVO))
                .setPayload("exp", System.currentTimeMillis()+60*60*1000)
                .setKey(securityProperties.getSecretKey().getBytes())
                .sign();
        settingUserVO.setToken(token);
        return Rep.ok(settingUserVO);
    }

    @Override
    public Rep<SettingUserVO> register(Req<SettingUserRegisterDTO, SettingUserVO> req) {
        SettingUserRegisterDTO data = req.getData();
        check(data);
        SettingUserEntity settingUserEntity = settingUserMapper.findByAccount(data.getAccount());
        if(ObjectUtil.isNotEmpty(settingUserEntity)){
            return Rep.error(500,"账号已被注册");
        }
        settingUserEntity = new SettingUserEntity();
        settingUserEntity.setUserName(data.getName());
        settingUserEntity.setUserAccount(data.getAccount());
        settingUserEntity.setUserPassword(encryptionPassword(data.getPassword(),data.getAccount()));
        settingUserMapper.insert(settingUserEntity);
        settingUserEntity.setTenantId(settingUserEntity.getId());
        settingUserMapper.updateById(settingUserEntity);
        return Rep.ok();
    }

    @Override
    public Rep<PageVO<SettingUserEntity>> find(Req<PageDTO<SettingUserEntity>, SettingUserVO> req) {
        PageDTO<SettingUserEntity> pageDTO = req.getData();
        Page<SettingUserEntity> page = new Page<SettingUserEntity>(pageDTO.getCurrent(), pageDTO.getSize());
        // 查询 唯一条件是要根据 权限查询
        SettingUserEntity settingUserEntity = pageDTO.getData();
        settingUserEntity = ObjectUtil.isEmpty(settingUserEntity)? new SettingUserEntity():settingUserEntity;
        IPage<SettingUserEntity> settingUserEntityIPage = settingUserMapper.find(page, settingUserEntity,req.getUser().getTenantId());
        PageVO<SettingUserEntity> pageVO = new PageVO<SettingUserEntity>(pageDTO)
                .setTotal(settingUserEntityIPage.getTotal())
                .setRecords(settingUserEntityIPage.getRecords());
        return Rep.ok(pageVO);
    }

    @Override
    public Rep<SettingUserEntity> edit(Req<SettingUserRegisterDTO, SettingUserVO> req) {
        SettingUserRegisterDTO data = req.getData();
        SettingUserVO user = req.getUser();
        check(data);
        if(ObjectUtil.isNotEmpty(data.getId())){
            SettingUserEntity old = settingUserMapper.findByAccounts(data.getId(),data.getAccount());
            AssertUtil.objIsNotNull(old, "账号已存在");
        }
        SettingUserEntity settingUserEntity = new SettingUserEntity();
        settingUserEntity.setId(data.getId());
        settingUserEntity.setUserName(data.getName());
        settingUserEntity.setUserMail(data.getMail());
        settingUserEntity.setUserAccount(data.getAccount());
        settingUserEntity.setUserPassword(encryptionPassword(data.getPassword(),data.getAccount()));
        settingUserEntity.setTenantId(user.getTenantId());
        saveOrUpdate(settingUserEntity);
        return Rep.ok();
    }

    @Override
    public Rep<SettingUserEntity> del(Req<SettingUserEntity, SettingUserVO> req) {
        SettingUserEntity data = req.getData();
        AssertUtil.objIsNull(data.getId(), "ID数据错误");
        settingUserMapper.delTrue(data.getId());
        return Rep.ok();
    }

    Map<String,String> codeMap = new ConcurrentHashMap<>();
    @Override
    public Map<String,Object> code() {
        String s = RandomUtil.randomString(5);
        codeMap.put(s,s);
        Thread thread = new Thread(() -> {
            String cacheCode = s;
            try {
                Thread.sleep(60 * 1000);
            } catch (InterruptedException e) {

            } finally {
                codeMap.remove(cacheCode);
            }
        });
        thread.setName("登录Code码有效期");
        thread.start();
        return new HashMap<String,Object>(){{
            put("ret", new HashMap<String,Object>(){{
                put("code", 200);
                put("message", "验证成功");
            }});
            put("data", s);
        }};
    }


    @Override
    public Rep<SettingUserEntity> editUser(Req<SettingUserEntity, SettingUserVO> req) {
        SettingUserEntity data = req.getData();
        SettingUserVO user = req.getUser();
        SettingUserEntity settingUserEntity = settingUserMapper.selectById(user.getId());
        AssertUtil.objIsNull(settingUserEntity, "用户不存在");
        if(StrUtil.isNotBlank(data.getUserName())) {
            settingUserEntity.setUserName(data.getUserName());
        }
        if(StrUtil.isNotBlank(data.getUserMail())) {
            settingUserEntity.setUserMail(data.getUserMail());
        }
        if(StrUtil.isNotBlank(data.getUserAccount())) {
            // 判断账号是否已存在
            SettingUserEntity old = settingUserMapper.findByAccounts(settingUserEntity.getId(),data.getUserAccount());
            AssertUtil.objIsNotNull(old, "账号已存在");
            settingUserEntity.setUserAccount(data.getUserAccount());
        }
        if(StrUtil.isNotBlank(data.getOkPassword())) {
//            AssertUtil.strEQ(data.getUserPassword(), data.getOkPassword(),"两次密码不一致");
            settingUserEntity.setUserPassword(encryptionPassword(data.getOkPassword(), data.getUserAccount()));
        }
        saveOrUpdate(settingUserEntity);
        return Rep.ok(settingUserEntity);
    }

    @Override
    public Rep<SettingUserEntity> findUser(Req<SettingUserRegisterDTO, SettingUserVO> req) {
        SettingUserVO user = req.getUser();
        SettingUserEntity settingUserEntity = settingUserMapper.selectById(user.getId());
        return Rep.ok(settingUserEntity);
    }

    @Override
    public Rep<List<SettingUserEntity>> findAll(Req<SettingUserEntity, SettingUserVO> req) {
        List<SettingUserEntity> settingUserEntities = settingUserMapper.findAll(req.getUser().getTenantId());
        if(CollUtil.isEmpty(settingUserEntities)){
            settingUserEntities = new ArrayList<>();
        }
        return Rep.ok(settingUserEntities);
    }

    @Override
    public Object getAuthUser(String token) throws BasicException {
        JWT jwt = JWT.of(token);
        // 验证
        if(!jwt.setKey(securityProperties.getSecretKey().getBytes()).verify()){
            throw new BasicException(BasicCode.BASIC_CODE_99986);
        }
        // 返回用户
        SettingUserVO userVO = JSONUtil.toBean(jwt.getPayload("user").toString(),SettingUserVO.class);
        return userVO;
    }

    @Override
    public List<String> getAuthorizeUrl(String token) throws BasicException {
        return null;
    }

    private void check(SettingUserRegisterDTO data){
        AssertUtil.objIsNull(data.getName(), "名称不能为空");
        AssertUtil.objIsNull(data.getAccount(), "账号不能为空");
        AssertUtil.objIsNull(data.getPassword(), "密码不能为空");
        AssertUtil.objIsNull(data.getOkPassword(), "确认密码不能为空");
        AssertUtil.strEQ(data.getPassword(), data.getOkPassword(),"两次密码不一致");
    }

    private String encryptionPassword(String password,String account){
        return SecureUtil.md5(password+account);
    }

    @Override
    public void packageCheck(PackagesBO.Item item,Integer tenantId) throws BasicException {
        if (!item.getOpen()) {
            throw new BasicException(500,"当前套餐不支持此业务");
        }
    }
}
